package co.yixiang.hw.service.impl;

import co.yixiang.hw.domain.YxUser;
import co.yixiang.hw.domain.YxWechatUser;
import co.yixiang.hw.repository.YxWechatUserRepository;
import co.yixiang.hw.service.YxWechatUserService;
import co.yixiang.hw.service.mapper.YxWechatUserMapper;
import co.yixiang.utils.*;
import co.yixiang.hw.repository.YxUserRepository;
import co.yixiang.hw.service.YxUserService;
import co.yixiang.hw.service.dto.YxUserDto;
import co.yixiang.hw.service.dto.YxUserQueryCriteria;
import co.yixiang.hw.service.mapper.YxUserMapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
// 默认不使用缓存
import org.springframework.cache.annotation.CacheConfig;
//import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
* @author Walert
* @date 2020-02-09
*/
@Service
@CacheConfig(cacheNames = "yxUser")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxUserServiceImpl implements YxUserService {

    @Resource
    private  YxUserRepository yxUserRepository;

    @Resource
    private  YxUserMapper yxUserMapper;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private RedisUtils redisUtils;

    @Autowired
    private YxWechatUserService wechatUserService;

    @Override
    //@Cacheable
    public List<YxUserDto> queryAll(YxUserQueryCriteria criteria){
        return yxUserMapper.toDto(yxUserRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    //@Cacheable(key = "#p0")
    public YxUserDto findById(Integer uid) {
        YxUser yxUser = yxUserRepository.findById(uid).orElseGet(YxUser::new);
        ValidationUtil.isNull(yxUser.getUid(),"YxUser","uid",uid);
        return yxUserMapper.toDto(yxUser);
    }

    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public YxUserDto create(YxUser resources) {
        return yxUserMapper.toDto(yxUserRepository.save(resources));
    }

    @Override
    //@CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(YxUser resources) {
        YxUser yxUser = yxUserRepository.findById(resources.getUid().intValue()).orElseGet(YxUser::new);
        ValidationUtil.isNull( yxUser.getUid(),"YxUser","id",resources.getUid());
        yxUser.copy(resources);
        yxUserRepository.save(yxUser);
    }

    @Override
//    @Cacheable
    public YxUserDto finByUserName(String userName) {
        YxUser user = (YxUser)redisUtils.get("yxUser::" + userName);
        if(user == null){
            List<YxUser> list = yxUserRepository.findByUsernameOrderByUidAsc(userName);
            System.out.println("我进来了 ~~~~~~~~~~~~~~~~~");
            if(list != null && list.size() > 0){
                user = list.get(0);
                redisUtils.set("yxUser::" + userName,user,2L, TimeUnit.HOURS);
            }
        }
        return yxUserMapper.toDto(user);
    }

    /**
     * 检查用户并自动注册方法
     *
     * @return
     */
    @Override
    public YxUserDto checkUserAndRegister(JSONObject params) {
        String phone = params.getString("phone");
        JSONObject userInfo = params.getJSONObject("userInfo");
        String openId = userInfo.getString("openId");
//        if(StringUtils.isBlank(phone)) phone = openId;
        Long addTime = System.currentTimeMillis()/1000L;
        YxUserDto yxUserDto = this.finByUserName(phone);
        if(yxUserDto == null){

            YxUser resource = new YxUser();
            resource.setAccount(phone);
            if(!phone.equals(openId)){
                resource.setPhone(phone);
            }
            resource.setUsername(phone);
            String pwd = "123456";
            if(userInfo != null){
                resource.setOpenId(openId);
                resource.setSex(userInfo.getInteger("gender"));
                resource.setAvatar(userInfo.getString("avatarUrl"));
                resource.setNickname(userInfo.getString("nickName"));
                pwd = openId;
            }else{
                resource.setOpenId(null);
                resource.setSex(1);
                resource.setAvatar("");
                resource.setNickname(openId);
            }
            resource.setStatus(1);
            resource.setPwd(passwordEncoder.encode(pwd));
            resource.setPassword(passwordEncoder.encode(pwd));
            resource.setAddTime(addTime.intValue());
            resource.setLoginType("wechat");
            yxUserDto = this.create(resource);
        }else{
            if(yxUserDto.getOpenId() == null){
                if(userInfo != null){
                    YxUser yxUser = yxUserMapper.toEntity(yxUserDto);
                    yxUser.setOpenId(openId);
                    yxUser.setSex(userInfo.getInteger("gender"));
                    yxUser.setAvatar(userInfo.getString("avatarUrl"));
                    yxUser.setNickname(userInfo.getString("nickName"));
                    yxUser.setPwd(passwordEncoder.encode(openId));
                    yxUser.setPassword(passwordEncoder.encode(openId));
                    this.update(yxUser);
                    redisUtils.del("yxUser::"+yxUser.getPhone());
                }
            }
        }
        if(userInfo != null){
            Long uid = yxUserDto.getUid();
            wechatUserService.asyncSaveWechatUserInfo(uid.intValue(),userInfo);
        }
        return yxUserDto;
    }
}
